///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __PHYSICAL_WORLD_H__
#define __PHYSICAL_WORLD_H__

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//#include <irrlicht.h>
#include "IrrArray.h"
#include "triangle3d.h"
#include "matrix4.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CPhysicalRoom
{
public:
	CPhysicalRoom();
	~CPhysicalRoom();

	void	ReallocateTriangleList(int size);
	int		AddTriangle(const irr::core::triangle3df& triangle);

	int		GetTrianglesCount() const
	{
		return m_triangles.size();
	}

	bool IsActive()	const
	{
		return m_isActive;		
	}

	void SetActive(bool active)		
	{	
		m_isActive = active;	
	}

	const irr::core::array<irr::core::triangle3df>&	GetTriangles()
	{	
		return m_triangles;	
	}

	irr::core::triangle3df& GetTriangle(int index)
	{
		return m_triangles[index];
	}

public:
	irr::core::array<irr::core::triangle3df>	m_triangles;
	bool										m_isActive;

#ifdef _DEBUG
public:
	char	m_roomName[128];
#endif //_DEBUG
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CPhysicalWorld
{
public:

	CPhysicalWorld();
	~CPhysicalWorld();

	int		AddCollisionRoom(const char* meshName, const irr::core::matrix4& transformMat);

	int		AddCollisionTriangleInRoom(int roomIndex, const irr::core::triangle3df& triangle);

	void	TransformCollisionTriangles(const irr::core::vector3df& invRadius);
	bool	CollideEllipsoidWithWorld(const irr::core::vector3df&	initpos, 
										const irr::core::vector3df&	finalpos, 
										const irr::core::vector3df&	radius, 
										irr::core::vector3df&		newpos,
										bool&						bFalling);

	bool	CollideRayWithWorld(const irr::core::vector3df& from, 
									const irr::core::vector3df& to, 
									irr::core::vector3df& intersectionPoint, 
									irr::core::triangle3df& intersectionTriangle);

	void	CollideWithTriangles();
	void	CollideWithWorld(int step);


	//void	ActivateCollisionRoom(int index, bool val)	
	//{	
	//	m_rooms[index]->SetActive(val);	
	//}

	irr::core::triangle3df&	GetTriangleFromRoom(int roomCollisionIndex, int triangleIndex)
	{
		return m_room->GetTriangle(triangleIndex);
	}

	int GetTriangleCount(int roomCollisionIndex)
	{
		return m_room->GetTrianglesCount();
	}

	void Clear()	{m_room->m_triangles.clear();}

protected:

	bool	GetLowestRoot(float a, float b, float c, float maxR, float* root);


	irr::core::array<irr::core::triangle3df>	m_triangles;
	//irr::core::array<CPhysicalRoom*>			m_rooms;
	CPhysicalRoom*								m_room;
	//int											m_noRooms;

	irr::core::vector3df						m_colESpaceStartPosition;
	irr::core::vector3df						m_colESpaceVelocity;
	irr::core::vector3df						m_colESpaceNormalizedVelocity;
	irr::core::vector3df						m_colESpaceResultPosition;
	irr::core::vector3df						m_colESpaceIntersectionPoint;
	irr::core::vector3df						m_colESpaceBasePoint;
	float										m_colNearestDistance;
	bool										m_colCollisionFound;
	int											m_colTriangleHits;

};

#endif //__PHYSICAL_WORLD_H__

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
